﻿using System;
using System.Collections.Generic;
using LoungeRepo.Contracts.Core;
using LoungeRepo.Contracts.Normalizer;
using LoungeRepo.Normalizer.DataStructures;

namespace LoungeRepo.Normalizer
{
    public class EntityNormalizer : IEntityNormalizer
    {
        private readonly EntityResolutionRequestDelegate resolveEntityReference;

        private readonly ObjectGraphNormalizer normalizer;
        private readonly ObjectGraphDenormalizer denormalizer;


        public EntityNormalizer(EntityResolutionRequestDelegate resolveEntityReference, ReportEntityDelegate reportEntity)
        {
            this.resolveEntityReference = resolveEntityReference;

            this.normalizer = new ObjectGraphNormalizer(reportEntity);
            this.denormalizer = new ObjectGraphDenormalizer(this.resolveEntityReference, reportEntity);
        }


        public IEnumerable<INormalizedEntity> Normalize(object entityObject)
        {
            ILoungeRepoEntityIdentity entityIdentity;
            if (this.normalizer.TryExtractEntityIdentity(entityObject, out entityIdentity))
            {
                return this.normalizer.NormalizeEntityGraph(entityObject, entityIdentity);
            }

            throw new NormalizerException(string.Format("Invalid entity type {0}! Must implement ILoungeRepoEntityIdentity", entityObject.GetType().FullName));
        }


        public object Denormalize(INormalizedEntity normalizedEntity)
        {
            return this.denormalizer.Denormalize(normalizedEntity);
        }


        public bool TryExtractEntityIdentity(object entityObject, out ILoungeRepoEntityIdentity entityIdentity)
        {
            return this.normalizer.TryExtractEntityIdentity(entityObject, out entityIdentity);
        }
    }
}
